import { TextureLoader, type Texture } from 'three'
import { enTextureType } from '../../domain/global/enumHelper'
import type { TextureParams } from '../../domain/global/typeHelper'
import type { TextureResult } from '../dto/TextureResult'

/**
 * Three的材质管理者，用于存储可复用的纹理
 */
export class ThreeTextureManager {
  private static _instance: ThreeTextureManager | null = null
  /**单一纹理缓存地图 */
  private _textureMap_single: Map<string, Texture> = new Map()

  private _textureLoader: TextureLoader = new TextureLoader()
  private constructor() {}

  public static getInstance(): ThreeTextureManager {
    if (ThreeTextureManager._instance === null) {
      ThreeTextureManager._instance = new ThreeTextureManager()
    }
    return ThreeTextureManager._instance
  }

  /** 加载纹理
   * @param params
   * @returns 返回一个回执，包含纹理和纹理id
   */
  public loadTexture(params: TextureParams): TextureResult {
    if (params.textureType === enTextureType.single) {
      return {
        texture: this.loadTexture_single(params),
        textureId: this.getTextureId(params),
      }
    } else {
      throw new Error('暂不支持该enTextureType类型')
    }
  }

  /** 根据TextureParams转化出一个textureId
   * @param params
   * @returns
   */
  private getTextureId(params: TextureParams): string {
    // 自己使用特定符号，按照特定的方式生成id，
    return params.textureType + ':' + params.imgUrl
  }

  private loadTexture_single(params: TextureParams): Texture {
    const url = params.imgUrl
    if (this._textureMap_single.has(url)) {
      return this._textureMap_single.get(url) as Texture
    } else {
      return this._textureLoader.load(
        url,
        (texture) => {
          this._textureMap_single.set(url, texture)
        },
        undefined,
        (err) => {
          throw err
        },
      )
    }
  }
}
